package com.gomro.galaxy.foundation.bi.engine.drive;

import cn.gomro.cloud.core.common.utils.BigDecimalUtils;
import cn.gomro.cloud.core.common.utils.GomroExceptionUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gomro.galaxy.core.commons.elastic.ElasticSearchRest;
import com.gomro.galaxy.core.commons.response.RestResponse;
import com.gomro.galaxy.foundation.bi.api.DataMartDriveApi;
import com.gomro.galaxy.foundation.bi.domain.Constants;
import com.gomro.galaxy.foundation.bi.domain.enumerater.VendorType;
import com.gomro.galaxy.foundation.bi.domain.model.analysis.*;
import com.gomro.galaxy.foundation.bi.engine.util.EngineUtils;
import com.gomro.galaxy.foundation.bi.query.DataMartQuery;
import com.gomro.galaxy.foundation.bi.query.SalesDataComparisonStaticsQuery;
import com.gomro.galaxy.foundation.bi.query.VirtualVendorQuotationQuery;
import com.gomro.galaxy.foundation.bi.service.SalesDataComparisonStaticsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.*;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;
//数据集市驱动器控制器
@Slf4j
@RestController
@RequestMapping("analysis")                    //数据集市驱动器Api
public class DataMartDriveController implements DataMartDriveApi {

    private ElasticSearchRest rest;  //
    private RestHighLevelClient client;  // 高级客户端
    private ObjectMapper mapper;  //对象映射
    private SalesDataComparisonStaticsService salesDataComparisonStaticsService;//销售数据比较service
    private static final int MAX_RESULT = 10_000;
    private static final String BiDataMartGoodsVolumeName = Constants.BiDataMartIndexPrefix + MarketGoodsTradingVolume.TableName;
    private static final String BiDataMartVendorTradingVolumeName = Constants.BiDataMartIndexPrefix + VendorTradingVolume.TableName;
    private static final String BiDataMartWorkbenchVendorQuotationName = Constants.BiDataMartIndexPrefix + WorkbenchVendorQuotation.TableName;
    private static final String BiDataMartVendorStatisticsName = Constants.BiDataMartIndexPrefix + VendorStatistics.TableName;
    private static final String BiDataVirtualVendorQuotationName = Constants.BiDataMartIndexPrefix + VirtualVendorQuotationVolume.TableName;

    public DataMartDriveController(RestHighLevelClient client, ObjectMapper mapper, SalesDataComparisonStaticsService salesDataComparisonStaticsService) {
        this.client = client;
        this.mapper = mapper;
        this.rest = new ElasticSearchRest(client, mapper);
        this.salesDataComparisonStaticsService = salesDataComparisonStaticsService;
    }

    @Override           //api 中的商品交易量                                  api商品交易记录
    public RestResponse<List<MarketGoodsTradingVolume>> pageGoodsTradingVolume(DataMartQuery query) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (StringUtils.isNotBlank(query.getStart())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("time").gte(query.getStart()));
        }
        if (StringUtils.isNotBlank(query.getEnd())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("time").lte(query.getEnd()));
        }
        if (StringUtils.isNotBlank(query.getVendorName())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("vendorName.keyword", "*" + query.getVendorName() + "*"));
        }

        if (StringUtils.isNotBlank(query.getName())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("name.keyword", "*" + query.getName() + "*"));
        }
        if (StringUtils.isNotBlank(query.getBrand())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("brand.keyword", "*" + query.getBrand() + "*"));
        }
        if (StringUtils.isNotBlank(query.getModel())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("model.keyword", "*" + query.getModel() + "*"));
        }
        boolean nonExport = Objects.isNull(query.getExport()) || !query.getExport();  //是否为导出类型
        if (nonExport && (query.getStartRow() + query.getLimit()) > MAX_RESULT) {  //导出数量是否超出规定
            return RestResponse.failed("查询数量过大, 请修改条件以控制 页数x每页显示数量 在" + MAX_RESULT + "条内!");
        }//字段排序构建器       排序建造者                                  获得排序
        FieldSortBuilder sort = SortBuilders.fieldSort(Optional.ofNullable(query.getSort()).orElse("name.keyword"))
                .order(SortOrder.valueOf(query.getDirection()));
        if (nonExport) {
            ElasticSearchRest.SearchResultClz<MarketGoodsTradingVolume> result = rest.searchAsClz(BiDataMartGoodsVolumeName, ElasticSearchRest.Page.of(query.getPage(), query.getLimit()),
                    boolQueryBuilder, Collections.singletonList(sort), null, MarketGoodsTradingVolume.class);
            if (Objects.isNull(result)) {
                return RestResponse.success(0, Collections.emptyList());
            }
            return RestResponse.success(result.getCount(), result.getData());
        } //时间值
        TimeValue timeValue = TimeValue.timeValueMinutes(3L);
        SearchResponse search = rest.search(BiDataMartGoodsVolumeName, ElasticSearchRest.Page.of(1, 100),
                boolQueryBuilder, Collections.singletonList(sort), null, timeValue);
        List<MarketGoodsTradingVolume> marketGoodsTradingVolume;
        try {
            marketGoodsTradingVolume = EngineUtils.scrollSearch(search, rest, mapper, timeValue, MarketGoodsTradingVolume.class);
        } catch (Exception e) {
            log.error("协议供应商报价统计 {} \n {}", ExceptionUtils.getMessage(e), ExceptionUtils.getStackTrace(e));
            return RestResponse.failed(ExceptionUtils.getMessage(e));
        }
        return RestResponse.success(search.getHits().getTotalHits().value, marketGoodsTradingVolume);
    }

    @Override
    public RestResponse<List<VendorTradingVolume>> pageVendorTradingVolume(DataMartQuery query) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (StringUtils.isNotBlank(query.getStart())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("time").gte(query.getStart()));
        }
        if (StringUtils.isNotBlank(query.getEnd())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("time").lte(query.getEnd()));
        }
        if (StringUtils.isNotBlank(query.getVendorName())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("organizationName.keyword", "*" + query.getVendorName() + "*"));
        }
        Integer limit = query.getLimit();

        List<BucketOrder> bucketOrders = Arrays.asList(BucketOrder.aggregation("quotationNum", false)
                , BucketOrder.aggregation("quotationTotal", false), BucketOrder.aggregation("orderGoodsNum", false)
                , BucketOrder.aggregation("orderGoodsTotal", false), BucketOrder.aggregation("refundNum", false)
                , BucketOrder.aggregation("refundTotal", false), BucketOrder.key(true));
        TermsAggregationBuilder orgTerm = AggregationBuilders.terms("org").field("organizationId").order(bucketOrders).size(query.getPage() * query.getLimit());
        AggregationBuilder vendorNameAgg = AggregationBuilders.topHits("organizationName").docValueField("organizationName.keyword").size(1);
        AggregationBuilder quotationNumAgg = AggregationBuilders.sum("quotationNum").field("quotationNum");
        AggregationBuilder quotationTotalAgg = AggregationBuilders.sum("quotationTotal").field("quotationTotal");
        AggregationBuilder orderGoodsNumAgg = AggregationBuilders.sum("orderGoodsNum").field("orderGoodsNum");
        AggregationBuilder orderGoodsTotalAgg = AggregationBuilders.sum("orderGoodsTotal").field("orderGoodsTotal");
        AggregationBuilder refundNumAgg = AggregationBuilders.sum("refundNum").field("refundNum");
        AggregationBuilder refundTotalAgg = AggregationBuilders.sum("refundTotal").field("refundTotal");
        orgTerm.subAggregation(quotationNumAgg).subAggregation(quotationTotalAgg).subAggregation(orderGoodsNumAgg)
                .subAggregation(orderGoodsTotalAgg).subAggregation(refundNumAgg).subAggregation(refundTotalAgg)
                .subAggregation(vendorNameAgg);
        AggregationBuilder count = AggregationBuilders.cardinality("count").field("organizationId").precisionThreshold(30000L);

        FieldSortBuilder sort = SortBuilders.fieldSort(Optional.ofNullable(query.getSort()).orElse("vendorId")).order(SortOrder.valueOf(query.getDirection()));
        SearchResponse search = rest.search(BiDataMartVendorTradingVolumeName, ElasticSearchRest.Page.of(query.getPage(), limit), boolQueryBuilder, Collections.singletonList(sort), Arrays.asList(orgTerm, count), null);
        Terms org = search.getAggregations().get("org");
        List<VendorTradingVolume> result = org.getBuckets().stream().skip(query.getStartRow()).map(bucket -> {
            double quotationNum = ((Sum) bucket.getAggregations().get("quotationNum")).getValue();
            double quotationTotal = ((Sum) bucket.getAggregations().get("quotationTotal")).getValue();
            double orderGoodsNum = ((Sum) bucket.getAggregations().get("orderGoodsNum")).getValue();
            double orderGoodsTotal = ((Sum) bucket.getAggregations().get("orderGoodsTotal")).getValue();
            double refundNum = ((Sum) bucket.getAggregations().get("refundNum")).getValue();
            double refundTotal = ((Sum) bucket.getAggregations().get("refundTotal")).getValue();
            String vendorName = ((TopHits) bucket.getAggregations().get("organizationName")).getHits().getHits()[0].getSourceAsMap().get("organizationName").toString();

            String vendorId = bucket.getKey().toString();
            return VendorTradingVolume.builder().organizationId(Long.valueOf(vendorId)).organizationName(vendorName)
                    .quotationNum(quotationNum).quotationTotal(quotationTotal).orderGoodsNum(orderGoodsNum)
                    .orderGoodsTotal(orderGoodsTotal).refundNum(refundNum).refundTotal(refundTotal).build();
        }).collect(Collectors.toList());
        Aggregation countAgg = search.getAggregations().get("count");
        return RestResponse.success(((Cardinality) countAgg).getValue(), result);
    }

    @Override
    public RestResponse<List<WorkbenchVendorQuotation>> pageInternalVendorQuotation(DataMartQuery query) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (StringUtils.isNotBlank(query.getStart())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("time").gte(query.getStart()));
        }
        if (StringUtils.isNotBlank(query.getEnd())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("time").lte(query.getEnd()));
        }
        if (StringUtils.isNotBlank(query.getVendorName())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("vendorName.keyword", "*" + query.getVendorName() + "*"));
        }
        boolQueryBuilder.must(QueryBuilders.matchQuery("type", VendorType.INTERNAL));
        FieldSortBuilder sort = SortBuilders.fieldSort(Optional.ofNullable(query.getSort()).orElse("vendorId")).order(SortOrder.valueOf(query.getDirection()));
        TimeValue timeValue = TimeValue.timeValueMinutes(3L);
        SearchResponse search = rest.search(BiDataMartWorkbenchVendorQuotationName, ElasticSearchRest.Page.of(query.getPage(), 100),
                boolQueryBuilder, Collections.singletonList(sort), null, timeValue);
        List<WorkbenchVendorQuotation> workbenchVendorQuotations;
        try {
            workbenchVendorQuotations = EngineUtils.scrollSearch(search, rest, mapper, timeValue, WorkbenchVendorQuotation.class);
        } catch (Exception e) {
            log.error("内部供应商报价统计 {} \n {}", ExceptionUtils.getMessage(e), ExceptionUtils.getStackTrace(e));
            return RestResponse.failed(ExceptionUtils.getMessage(e));
        }
        return RestResponse.success(search.getHits().getTotalHits().value, workbenchVendorQuotations);
    }

    @Override
    public RestResponse<List<WorkbenchVendorQuotation>> pageProtocolVendorQuotation(DataMartQuery query) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (StringUtils.isNotBlank(query.getStart())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("time").gte(query.getStart()));
        }
        if (StringUtils.isNotBlank(query.getEnd())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("time").lte(query.getEnd()));
        }
        if (StringUtils.isNotBlank(query.getVendorName())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("vendorName.keyword", "*" + query.getVendorName() + "*"));
        }
        boolQueryBuilder.must(QueryBuilders.matchQuery("type", VendorType.PROTOCOL));
        FieldSortBuilder sort = SortBuilders.fieldSort(Optional.ofNullable(query.getSort()).orElse("vendorId")).order(SortOrder.valueOf(query.getDirection()));
        TimeValue timeValue = TimeValue.timeValueMinutes(3L);
        SearchResponse search = rest.search(BiDataMartWorkbenchVendorQuotationName, ElasticSearchRest.Page.of(query.getPage(), 100),
                boolQueryBuilder, Collections.singletonList(sort), null, timeValue);
        List<WorkbenchVendorQuotation> workbenchVendorQuotations;
        try {
            workbenchVendorQuotations = EngineUtils.scrollSearch(search, rest, mapper, timeValue, WorkbenchVendorQuotation.class);
        } catch (Exception e) {
            log.error("协议供应商报价统计 {} \n {}", ExceptionUtils.getMessage(e), ExceptionUtils.getStackTrace(e));
            return RestResponse.failed(ExceptionUtils.getMessage(e));
        }
        return RestResponse.success(search.getHits().getTotalHits().value, workbenchVendorQuotations);
    }

    @Override
    public RestResponse<List<VendorStatisticsView>> pageVendorStatistics(DataMartQuery query) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (StringUtils.isNotBlank(query.getStart())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("time").gte(query.getStart()));
        }
        if (StringUtils.isNotBlank(query.getEnd())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("time").lte(query.getEnd()));
        }
        if (StringUtils.isNotBlank(query.getVendorName())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("vendorName.keyword", "*" + query.getVendorName() + "*"));
        }
        if (!CollectionUtils.isEmpty(query.getVendorIds())) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("vendorId", query.getVendorIds()));
        }
        List<BucketOrder> bucketOrders = Arrays.asList(BucketOrder.aggregation("participateNum", false)
                , BucketOrder.aggregation("quotationNum", false), BucketOrder.aggregation("picketedNum", false)
                , BucketOrder.aggregation("orderNum", false), BucketOrder.aggregation("orderTotal", false)
                , BucketOrder.aggregation("missedOrder", false), BucketOrder.aggregation("unitTimeQuotationNum", false)
                , BucketOrder.aggregation("purchaseGoodsNum", false), BucketOrder.aggregation("goodsNum", false)
                , BucketOrder.aggregation("brandNum", false), BucketOrder.key(true));
        TermsAggregationBuilder orgTerm = AggregationBuilders.terms("terms").field("vendorId").order(bucketOrders).size(query.getPage() * query.getLimit());
        AggregationBuilder vendorId = AggregationBuilders.topHits("vendorId").docValueField("vendorId").size(1);
        AggregationBuilder vendorName = AggregationBuilders.topHits("vendorName").docValueField("vendorName.keyword").size(1);
        AggregationBuilder goodsNum = AggregationBuilders.sum("goodsNum").field("goodsNum");
        AggregationBuilder brandNum = AggregationBuilders.sum("brandNum").field("brandNum");
        AggregationBuilder participateNum = AggregationBuilders.sum("participateNum").field("participateNum");
        AggregationBuilder quotationNum = AggregationBuilders.sum("quotationNum").field("quotationNum");
        AggregationBuilder picketedNum = AggregationBuilders.sum("picketedNum").field("picketedNum");
        AggregationBuilder orderNum = AggregationBuilders.sum("orderNum").field("orderNum");
        AggregationBuilder orderTotal = AggregationBuilders.sum("orderTotal").field("orderTotal");
        AggregationBuilder missedOrder = AggregationBuilders.sum("missedOrder").field("missedOrder");
        AggregationBuilder unitTimeQuotationNum = AggregationBuilders.sum("unitTimeQuotationNum").field("unitTimeQuotationNum");
        AggregationBuilder purchaseGoodsNum = AggregationBuilders.sum("purchaseGoodsNum").field("purchaseGoodsNum");
        AggregationBuilder responsible = AggregationBuilders.topHits("responsible").docValueField("responsible.keyword").sort("time", SortOrder.DESC).size(1);
        orgTerm.subAggregation(vendorId).subAggregation(vendorName).subAggregation(goodsNum).subAggregation(brandNum)
                .subAggregation(participateNum).subAggregation(quotationNum).subAggregation(picketedNum).subAggregation(orderNum)
                .subAggregation(orderTotal).subAggregation(missedOrder).subAggregation(unitTimeQuotationNum)
                .subAggregation(purchaseGoodsNum).subAggregation(responsible);

        AggregationBuilder count = AggregationBuilders.cardinality("count").field("vendorId").precisionThreshold(30000L);
        SearchResponse search = rest.search(BiDataMartVendorStatisticsName, ElasticSearchRest.Page.of(1, 0), boolQueryBuilder, null, Arrays.asList(orgTerm, count), null);
        Terms org = search.getAggregations().get("terms");
        List<VendorStatisticsView> result = org.getBuckets().stream().skip(query.getStartRow()).map(bucket -> {
            int goodsNumAgg = ((int) (((Sum) bucket.getAggregations().get("goodsNum")).getValue()));
            int brandNumAgg = ((int) (((Sum) bucket.getAggregations().get("brandNum")).getValue()));
            int participateNumAgg = ((int) (((Sum) bucket.getAggregations().get("participateNum")).getValue()));
            double quotationNumAgg = (((Sum) bucket.getAggregations().get("quotationNum")).getValue());
            int picketedNumAgg = ((int) (((Sum) bucket.getAggregations().get("picketedNum")).getValue()));
            int orderNumAgg = ((int) (((Sum) bucket.getAggregations().get("orderNum")).getValue()));
            double orderTotalAgg = ((Sum) bucket.getAggregations().get("orderTotal")).getValue();
            int missedOrderAgg = ((int) (((Sum) bucket.getAggregations().get("missedOrder")).getValue()));
            double unitTimeQuotationNumAgg = (((Sum) bucket.getAggregations().get("unitTimeQuotationNum")).getValue());
            double purchaseGoodsNumAgg = (((Sum) bucket.getAggregations().get("purchaseGoodsNum")).getValue());
            String responsibleName = ((TopHits) bucket.getAggregations().get("responsible")).getHits().getHits()[0].getSourceAsMap().get("responsible").toString();
            String vendorIdTop = ((TopHits) bucket.getAggregations().get("vendorId")).getHits().getHits()[0].getSourceAsMap().get("vendorId").toString();
            String vendorNameTop = ((TopHits) bucket.getAggregations().get("vendorName")).getHits().getHits()[0].getSourceAsMap().get("vendorName").toString();
//
            boolean nonExistsParticipateNum = Objects.equals(0, participateNumAgg);
            boolean nonExistsQuotationNum = Objects.equals(0.0, quotationNumAgg);
            double quotationRate = nonExistsParticipateNum ? 0.0 : BigDecimalUtils.round(quotationNumAgg / participateNumAgg, 2);
            double thirtySixHourQuotationRate = nonExistsQuotationNum ? 0.0 : BigDecimalUtils.round(unitTimeQuotationNumAgg / quotationNumAgg, 2);
            double orderRate = nonExistsQuotationNum ? 0.0 : BigDecimalUtils.round(purchaseGoodsNumAgg / quotationNumAgg, 2);
            return VendorStatisticsView.builder().vendorId(Long.valueOf(vendorIdTop)).vendorName(vendorNameTop)
                    .responsible(responsibleName).goodsNum((goodsNumAgg)).brandNum(brandNumAgg)
                    .quotationNum((int) quotationNumAgg).participateNum(participateNumAgg).picketedNum(picketedNumAgg)
                    .orderNum(orderNumAgg).orderTotal(orderTotalAgg).missedOrder(missedOrderAgg)
                    .thirtySixHourQuotationRate(Objects.equals(thirtySixHourQuotationRate, 0.0) ? "" : thirtySixHourQuotationRate * 100 + "%")
                    .orderRate(Objects.equals(orderRate, 0.0) ? "" : orderRate * 100 + "%")
                    .quotationRate(Objects.equals(quotationRate, 0.0) ? "" : quotationRate * 100 + "%")
                    .build();
        }).collect(Collectors.toList());
        Aggregation countAgg = search.getAggregations().get("count");
        return RestResponse.success(((Cardinality) countAgg).getValue(), result);
    }

    /**
     * 供应商数据统计
     *
     * @param query
     * @return
     */
    @Override
    public RestResponse<List<SalesDataComparisonStatisticsVolumeView>> pageSalesStatistics(SalesDataComparisonStaticsQuery query) {
        return salesDataComparisonStaticsService.page(query);
    }

    /**
     * 虚拟供应商数据统计查询
     *
     * @param query
     * @return
     */
    @Override
    public RestResponse<List<VirtualVendorQuotationVolume>> pageVirtualVendorQuotationVolume(VirtualVendorQuotationQuery query) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (StringUtils.isNotBlank(query.getInquiryTimeStart())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("inquiryTime").gte(query.getInquiryTimeStart()));
        }
        if (StringUtils.isNotBlank(query.getInquiryTimeEnd())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("inquiryTime").lte(query.getInquiryTimeEnd()));
        }

        if (StringUtils.isNotBlank(query.getQuotationTimeStart())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("quotationTime").gte(query.getQuotationTimeStart()));
        }
        if (StringUtils.isNotBlank(query.getQuotationTimeEnd())) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("quotationTime").lte(query.getQuotationTimeEnd()));
        }
        if (StringUtils.isNotBlank(query.getVendorName())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("vendorName.keyword", "*" + query.getVendorName() + "*"));
        }

        if (StringUtils.isNotBlank(query.getProductManager())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("productManager.keyword", "*" + query.getProductManager() + "*"));
        }
        if (StringUtils.isNotBlank(query.getCustomerName())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("inquiryOrganizationName.keyword", "*" + query.getCustomerName() + "*"));
        }
        if (StringUtils.isNotBlank(query.getInquiryGoodsStatus())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("inquiryGoodsStatus", "*" + query.getInquiryGoodsStatus() + "*"));
        }
        if (StringUtils.isNotBlank(query.getQuotationStatus())) {
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("quotationStatus", "*" + query.getQuotationStatus() + "*"));
        }
        if (Objects.nonNull(query.getPartakeCount())) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("partakeCount", query.getPartakeCount()));

        }
        if (Objects.nonNull(query.getQuoteCount())) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("quoteCount", query.getQuoteCount()));

        }

        boolean nonExport = Objects.isNull(query.getExport()) || !query.getExport();
        if (nonExport && (query.getStartRow() + query.getLimit()) > MAX_RESULT) {
            return RestResponse.failed("查询数量过大, 请修改条件以控制 页数x每页显示数量 在" + MAX_RESULT + "条内!");
        }
        FieldSortBuilder sort = SortBuilders.fieldSort(Optional.ofNullable(query.getSort()).orElse("name.keyword"))
                .order(SortOrder.valueOf(query.getDirection()));
        if (nonExport) {
            ElasticSearchRest.SearchResultClz<VirtualVendorQuotationVolume> result = rest.searchAsClz(BiDataVirtualVendorQuotationName, ElasticSearchRest.Page.of(query.getPage(), query.getLimit()),
                    boolQueryBuilder, Collections.singletonList(sort), null, VirtualVendorQuotationVolume.class);
            if (Objects.isNull(result)) {
                return RestResponse.success(0, Collections.emptyList());
            }
            return RestResponse.success(result.getCount(), result.getData());
        }
        TimeValue timeValue = TimeValue.timeValueMinutes(3L);
        SearchResponse search = rest.search(BiDataVirtualVendorQuotationName, ElasticSearchRest.Page.of(1, 100),
                boolQueryBuilder, Collections.singletonList(sort), null, timeValue);
        List<VirtualVendorQuotationVolume> virtualVendorQuotationVolume;
        try {
            virtualVendorQuotationVolume = EngineUtils.scrollSearch(search, rest, mapper, timeValue, VirtualVendorQuotationVolume.class);
        } catch (Exception e) {
            GomroExceptionUtils.error(e, "运营工作台虚拟供应商报价统计");
            return RestResponse.failed(ExceptionUtils.getMessage(e));
        }
        return RestResponse.success(search.getHits().getTotalHits().value, virtualVendorQuotationVolume);
    }
}
